from video_reptile import user_agent
import urllib.request as ur
import urllib.parse as up
import zlib
import re
import json
import requests
import lxml.etree as le
import os
from tqdm import tqdm
import math


BASE_DIR = os.getcwd()

def get_html(url):
    response = requests.get(
        url=url,
        headers={
            'User-Agent':user_agent.get_user_agent_pc()
        },
    )

    if response.status_code < 200 or response.status_code >= 300:
        raise Exception("code:{0}，获取网页源码失败".format(response.status_code))

    return response.content.decode('utf-8')

def download_tqdm(path, filename, response):
    with open(path + filename, 'wb') as f:
        total_size = response.headers['Content-Length']
        content_size = math.ceil(int(total_size) / 1024)
        for data in tqdm(iterable=response.iter_content(1024), total=content_size, unit='k',
                         desc=filename):
            f.write(data)


def get_video(url, cookie=""):
    html = get_html(url)

    html_x = le.HTML(html)

    # 获取视频名称
    video_name = html_x.xpath('//div[@id="viewbox_report"]/h1/span/text()')[0]
    video_name = re.sub('[/\\s-]', '_', video_name)

    # 检查是否存在该视频的文件夹，如果不存在则创建以视频名称为命名的文件夹
    video_path = BASE_DIR + '\\static\\files\\MV\\' + video_name + '\\'
    if not os.path.exists(video_path):
        os.makedirs(video_path)

    # 查看视频文件夹是否存在视频，如果不存在则进行爬取下载，如果存在则直接返回结果
    for root, dirs, files in os.walk(video_path):
        filelist = list(files)

    if len(filelist) > 0 and (video_name + '.mp4') in filelist:
        return {
            'count':len(filelist),
            'filename':video_name
        }

    # 获取视频信息
    video_pattern = '<script>window.__playinfo__=(.*?)</script>'
    res_json = re.findall(video_pattern, html)[0]
    res_dict = json.loads(res_json)
    if 'dash' in res_dict['data']:
        video = res_dict['data']['dash']['video'][0]
        audio = res_dict['data']['dash']['audio'][0]
        video_url = video['baseUrl']
        audio_url = audio['baseUrl']

        headers = {
            'Access-Control-Request-Headers': 'range',
            'Access-Control-Request-Method': 'GET',
            'Origin': 'https://www.bilibili.com',
            'Referer': url,
            'Cookie': cookie if len(cookie) > 0 else "",
            'Sec-Fetch-Mode': 'no-cors',
            'User-Agent': user_agent.get_user_agent_pc()
        }
        video_response = requests.get(
            url=video_url,
            stream=True,
            headers=headers
        )

        if video_response.status_code < 200 or video_response.status_code >= 300:
            raise Exception("code:{0}，获取视频失败".format(video_response.status_code))

        audio_response = requests.get(
            url=audio_url,
            stream=True,
            headers=headers
        )

        if audio_response.status_code < 200 or audio_response.status_code >= 300:
            raise Exception("code:{0}，获取音频失败".format(audio_response.status_code))

        download_tqdm(video_path, video_name+'.mp3', audio_response)
        download_tqdm(video_path, video_name+'.mp4', video_response)

        return {
            'count':2,
            'filename': video_name
        }
    elif 'durl' in res_dict['data']:
        # https://www.bilibili.com/video/av3145765?from=search&seid=171658183153199378
        cid = res_dict['data']['durl'][0]['url'].split('/')[6]
        avid = url.split('/')[4].split('?')[0][2:]
        headers = {
            'Accept': 'application / json, text / javascript, * / *; q = 0.01',
            'Origin': 'https://www.bilibili.com',
            'Referer': url,
            'Cookie': cookie if len(cookie) > 0 else "",
            'Sec-Fetch-Mode': 'cors',
            'User-Agent': user_agent.get_user_agent_pc()
        }
        get_url_params = {
            'avid': avid,
            'cid': cid,
            'bvid': '',
            'qn': res_dict['data']['accept_quality'][0],
            'type': '',
            'otype': 'json',
            'fnver': '0',
            'fnval': '16',
            'session': res_dict['session'],
        }
        get_url_url = 'https://api.bilibili.com/x/player/playurl'

        get_url_response = requests.get(
            url=get_url_url,
            headers=headers,
            params=get_url_params
        ).content.decode('utf-8')

        get_url_response_dict = json.loads(get_url_response)

        if get_url_response_dict['code'] == 0:
            video_url = get_url_response_dict['data']['durl'][0]['url']

        video_response = requests.get(
            url=video_url,
            stream=True,
            headers=headers
        )

        if video_response.status_code < 200 or video_response.status_code >= 300:
            raise Exception("code:{0}，获取视频失败".format(video_response.status_code))

        download_tqdm(video_path, video_name+'.mp4', video_response)

        return {
            'count': 1,
            'filename': video_name
        }
        # 调用iter_content，一块一块的遍历要下载的内容，搭配stream=True，此时才开始真正的下载
        # iterable：可迭代的进度条
        # total：预期的迭代次数。
        #        如果未指定，则在可能的情况下使用len（iterable）。
        #        如果使用float（“ inf”）或作为最后手段，则仅显示基本进度统计信息（无ETA，无进度栏）。
        #        如果gui为True并且此参数需要后续更新，请指定一个初始的任意大正数，例如 9e9。
        # unit：用于定义每次迭代单位的字符串[默认值：it]
        # desc：进度条的前缀
